use std::time::{Duration, SystemTime};
use tonic::transport::{Channel, ClientTlsConfig};
use anyhow::{Result, anyhow};
use crate::config::{AgentConfig, RetryConfig};
use crate::rpc_server::rpc_server::config_monitor_s_client::ConfigMonitorSClient;

pub struct ConnectionManager {
    client: Option<ConfigMonitorClient<Channel>>,
    server_urls: Vec<String>,
    current_server: usize,
    retry_config: RetryConfig,
    last_success: SystemTime,
    connection_attempts: u32,
}

impl ConnectionManager {
    pub fn new(config: &AgentConfig) -> Self {
        Self {
            client: None,
            server_urls: config.server_urls.clone(),
            current_server: 0,
            retry_config: config.retry_config.clone(),
            last_success: SystemTime::now(),
            connection_attempts: 0,
        }
    }

    pub async fn ensure_connection(&mut self) -> Result<&mut ConfigMonitorClient<Channel>> {
        // 检查现有连接是否健康
        if self.is_connection_healthy().await {
            return Ok(self.client.as_mut().unwrap());
        }

        // 尝试重新连接
        self.reconnect_with_retry().await
    }

    async fn is_connection_healthy(&mut self) -> bool {
        if let Some(client) = &mut self.client {
            // 尝试发送一个简单的健康检查请求
            match tokio::time::timeout(
                Duration::from_secs(5),
                client.ping(tonic::Request::new(crate::rpc_client::PingRequest {}))
            ).await {
                Ok(Ok(_)) => {
                    self.last_success = SystemTime::now();
                    return true;
                }
                _ => {
                    log::warn!("连接健康检查失败，需要重新连接");
                }
            }
        }
        false
    }

    async fn reconnect_with_retry(&mut self) -> Result<&mut ConfigMonitorClient<Channel>> {
        let mut delay = self.retry_config.initial_delay();
        
        for attempt in 0..self.retry_config.max_retries {
            self.connection_attempts += 1;
            
            // 尝试连接所有Server地址
            for server_idx in 0..self.server_urls.len() {
                let server_url = &self.server_urls[server_idx];
                
                log::info!("尝试连接Server {} (第{}次尝试)", server_url, attempt + 1);
                
                match self.try_connect(server_url).await {
                    Ok(client) => {
                        self.client = Some(client);
                        self.current_server = server_idx;
                        self.last_success = SystemTime::now();
                        self.connection_attempts = 0;
                        
                        log::info!("成功连接到Server: {}", server_url);
                        return Ok(self.client.as_mut().unwrap());
                    }
                    Err(e) => {
                        log::warn!("连接Server {}失败: {}", server_url, e);
                    }
                }
            }
            
            // 如果不是最后一次尝试，等待后重试
            if attempt < self.retry_config.max_retries - 1 {
                log::info!("等待 {}s 后重试...", delay.as_secs());
                tokio::time::sleep(delay).await;
                
                // 指数退避
                delay = std::cmp::min(
                    Duration::from_secs_f64(delay.as_secs_f64() * self.retry_config.backoff_multiplier),
                    self.retry_config.max_delay()
                );
            }
        }
        
        Err(anyhow!("所有Server连接失败，已尝试{}次", self.retry_config.max_retries))
    }

    async fn try_connect(&self, server_url: &str) -> Result<ConfigMonitorClient<Channel>> {
        let timeout = Duration::from_secs(10);
        
        let channel = if server_url.starts_with("https://") {
            // HTTPS连接
            let tls_config = ClientTlsConfig::new()
                .ca_certificate(tokio::fs::read("certs/ca-cert.pem").await?)
                .identity(
                    tokio::fs::read("certs/client-cert.pem").await?,
                    tokio::fs::read("certs/client-key.pem").await?
                );
            
            Channel::from_shared(server_url.to_string())?
                .timeout(timeout)
                .tls_config(tls_config)?
                .connect()
                .await?
        } else {
            // HTTP连接
            Channel::from_shared(server_url.to_string())?
                .timeout(timeout)
                .connect()
                .await?
        };

        Ok(ConfigMonitorClient::new(channel))
    }

    pub fn get_current_server(&self) -> Option<&String> {
        if self.current_server < self.server_urls.len() {
            Some(&self.server_urls[self.current_server])
        } else {
            None
        }
    }

    pub fn get_connection_stats(&self) -> ConnectionStats {
        ConnectionStats {
            current_server: self.get_current_server().cloned(),
            last_success: self.last_success,
            connection_attempts: self.connection_attempts,
            is_connected: self.client.is_some(),
        }
    }
}

#[derive(Debug, Clone)]
pub struct ConnectionStats {
    pub current_server: Option<String>,
    pub last_success: SystemTime,
    pub connection_attempts: u32,
    pub is_connected: bool,
}

impl ConnectionStats {
    pub fn time_since_last_success(&self) -> Duration {
        SystemTime::now().duration_since(self.last_success).unwrap_or_default()
    }
}